package com.sh.rbac.core.encrypt.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.SM2;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 加密工具类
 *
 * @author wb
 * @since 2025-10-20
 */
public class EncryptUtils {

    private static final String PUBLIC_KEY = "publicKey";
    private static final String PRIVATE_KEY = "privateKey";

    /**
     * base64 加密
     *
     * @param data 待加密数据
     * @return 加密后的数据
     */
    public static String encryptByBase64(String data) {
        return Base64.encode(data, StandardCharsets.UTF_8);
    }

    /**
     * base64 解密
     *
     * @param data 待解密数据
     * @return 解密后的数据
     */
    public static String decryptByBase64(String data) {
        return Base64.decodeStr(data, StandardCharsets.UTF_8);
    }


    /**
     * aes 加密
     *
     * @param data   待加密数据
     * @param aesKey 密钥
     * @return 加密后的数据
     */
    public static String encryptByAes(String data, String aesKey) {
        return SecureUtil.aes(aesKey.getBytes(StandardCharsets.UTF_8))
                .encryptBase64(data, StandardCharsets.UTF_8);
    }

    /**
     * aes 加密
     *
     * @param data   待加密数据
     * @param aesKey 密钥
     * @return 加密后的数据
     */
    public static String encryptByAesHex(String data, String aesKey) {
        return SecureUtil.aes(aesKey.getBytes(StandardCharsets.UTF_8))
                .encryptHex(data, StandardCharsets.UTF_8);
    }


    /**
     * aes 解密
     *
     * @param data   待解密数据
     * @param aesKey 密钥
     * @return 解密后的数据
     */
    public static String decryptByAes(String data, String aesKey) {
        return SecureUtil.aes(aesKey.getBytes(StandardCharsets.UTF_8))
                .decryptStr(data, StandardCharsets.UTF_8);
    }

    /**
     * 生成 RSA 密钥对
     *
     * @return 密钥对
     */
    public static Map<String, String> generateRsaKey() {
        RSA rsa = SecureUtil.rsa();
        return Map.of(
                PUBLIC_KEY, rsa.getPublicKeyBase64(),
                PRIVATE_KEY, rsa.getPrivateKeyBase64()
        );
    }


    /**
     * rsa 公钥加密
     *
     * @param data      待加密数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public static String encryptByRsa(String data, String publicKey) {
        RSA rsa = SecureUtil.rsa(null, publicKey);
        return rsa.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
    }

    /**
     * rsa 公钥加密
     *
     * @param data      待加密数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public static String encryptByRsaHex(String data, String publicKey) {
        RSA rsa = SecureUtil.rsa(null, publicKey);
        return rsa.encryptHex(data, StandardCharsets.UTF_8, KeyType.PublicKey);
    }


    /**
     * rsa 私钥解密
     *
     * @param data       待解密数据
     * @param privateKey 私钥
     * @return 解密后的数据
     */
    public static String decryptByRsa(String data, String privateKey) {
        RSA rsa = SecureUtil.rsa(privateKey, null);
        return rsa.decryptStr(data, KeyType.PrivateKey, StandardCharsets.UTF_8);
    }

    /**
     * 生成 SM2 密钥对
     *
     * @return 密钥对
     */
    public static Map<String, String> generateSm2Key() {
        SM2 sm2 = SmUtil.sm2();
        return Map.of(
                PUBLIC_KEY, sm2.getPublicKeyBase64(),
                PRIVATE_KEY, sm2.getPrivateKeyBase64()
        );
    }

    /**
     * sm2 公钥加密
     *
     * @param data      待加密数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public static String encryptBySm2(String data, String publicKey) {
        SM2 sm2 = SmUtil.sm2(null, publicKey);
        return sm2.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
    }

    /**
     * sm2 公钥加密
     *
     * @param data      待加密数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public static String encryptBySm2Hex(String data, String publicKey) {
        SM2 sm2 = SmUtil.sm2(null, publicKey);
        return sm2.encryptHex(data, StandardCharsets.UTF_8, KeyType.PublicKey);
    }

    /**
     * sm2 私钥解密
     *
     * @param data       待解密数据
     * @param privateKey 私钥
     * @return 解密后的数据
     */
    public static String decryptBySm2(String data, String privateKey) {
        SM2 sm2 = SmUtil.sm2(privateKey, null);
        return sm2.decryptStr(data, KeyType.PrivateKey, StandardCharsets.UTF_8);
    }


    /**
     * sm4 加密
     *
     * @param data   待加密数据
     * @param sm4Key 密钥
     * @return 加密后的数据
     */
    public static String encryptBySm4(String data, String sm4Key) {
        return SmUtil.sm4(sm4Key.getBytes(StandardCharsets.UTF_8)).encryptBase64(data, StandardCharsets.UTF_8);
    }

    /**
     * sm4 加密
     *
     * @param data   待加密数据
     * @param sm4Key 密钥
     * @return 加密后的数据
     */
    public static String encryptBySm4Hex(String data, String sm4Key) {
        return SmUtil.sm4(sm4Key.getBytes(StandardCharsets.UTF_8)).encryptHex(data, StandardCharsets.UTF_8);
    }


    /**
     * sm4 解密
     *
     * @param data   待解密数据
     * @param sm4Key 密钥
     * @return 解密后的数据
     */
    public static String decryptBySm4(String data, String sm4Key) {
        return SmUtil.sm4(sm4Key.getBytes(StandardCharsets.UTF_8)).decryptStr(data, StandardCharsets.UTF_8);
    }
}
